package cate.game.role.res.guild.po.envelope;

import cate.common.table.d.GDGuild;
import cate.common.table.d.GDObj;
import cate.game.GameBody;
import cate.game.res.MixRes;
import cate.game.res.MixResItem;
import cate.common.table.guild.GuildEnvelopeRow;
import cate.game.role.Role;
import cate.game.role.res.guild.msg.envelope.DrawEnvelopeResp;
import cate.game.role.show.frame.HeadFrameVO;
import cate.game.role.show.icon.HeadIconVO;
import cate.game.util.GameKit;
import com.fasterxml.jackson.annotation.JsonIgnore;
import easy.java.dev.note.NoteClass;
import easy.java.dev.note.NoteField;
import easy.java.practice.errorcode.EcResult;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.annotation.Transient;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

@NoteClass(value = "单个公会红包信息")
public class GuildEnvelopeDetailPO {
    @NoteField(value = "红包唯一ID")
    public String uid;

    @NoteField(value = "红包类型ID")
    public int tid;

    @NoteField(value = "红包剩余金额")
    public int remainAmount;

    @NoteField(value = "货币类型")
    public int mtype;

    @NoteField(value = "红包发放时间")
    public long issueTime;

    @NoteField(value = "红包发放者ID")
    public String issuerId;

    @NoteField("红包发放者性别")
    public byte sex;

    @NoteField("红包发放者等级")
    public int level;

    @NoteField(value = "头像")
    public HeadIconVO headIcon;

    @NoteField("头像框")
    public HeadFrameVO headFrame;

    @NoteField(value = "红包发放者姓名")
    public String issuerName;

    @NoteField(value = "红包发放者职位")
    public byte issuerPos;

    @NoteField(value = "抢到红包的成员列表")
    public List<GuildEnvelopeMemberPO> members;

    @Transient
    @JsonIgnore
    public transient GuildEnvelopeRow row;

    @JsonIgnore
    public GuildEnvelopeRow getRow(GameBody game) {
        if (row == null) {
            row = game.table.guild.envelope.get(this.tid);
        }
        return row;
    }

    public GuildEnvelopeDetailPO() {
    }

    public GuildEnvelopeDetailPO(Role role, GuildEnvelopeRow tpl) {
        this.uid = GameKit.uid();
        this.tid = tpl.id;
        this.remainAmount = tpl.amount;
        this.mtype = tpl.mtype;
        issueTime = System.currentTimeMillis();
        issuerId = role.getUid();
        issuerName = role.getBase().name;
        issuerPos = role.getRes().guild.getPos();
        this.headFrame = role.getBase().headFrame;
        this.headIcon = role.getBase().headIcon;
        this.sex = role.getBase().sex;
        this.level = role.getBase().level;
        members = new ArrayList<>();
    }

    /**
     * 判断红包是否过期
     */
    public boolean isExpire() {
        return (System.currentTimeMillis() - issueTime) / 100000
                > GDGuild.redEnvelope.RED_ENVELOPE_KEEP_HOUR * 6 * 6;
    }

    /**
     * 判断成员是否抢过红包
     */
    public boolean containMember(String idHex) {
        for (GuildEnvelopeMemberPO member : members) {
            if (StringUtils.equals(idHex, member.uid)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 抢红包
     */
    public EcResult draw(Role role) {
        EcResult r = new EcResult();
        GuildEnvelopeRow row = getRow(role.getGame());
        if (containMember(role.getUid())) {
            role.getGame().notice.message(role, "你已经抢过该红包");
            r.fail("你已经抢过该红包");
            return r;
        }
        // 当前剩余的红包个数
        int num = row.redEnvelopeNum - members.size();
        if (num <= 0) {
            role.getGame().notice.message(role, "当前红包已经领完");
            return new EcResult().fail();
        }
        // 随机出本次抢到的金额
        int randomNum = genRandomNum(row, this.remainAmount, num);
        this.remainAmount -= randomNum;
        GuildEnvelopeMemberPO member = new GuildEnvelopeMemberPO(role, randomNum);
        // 记录本次抢红包的信息
        members.add(member);
        // 发放奖励

        MixRes reward = new MixRes();
        reward.addItem(new MixResItem(GDObj.Type.NUM, row.mtype, randomNum));
        reward.add(role);

        // 通知前端这个红包抢到了
        role.sendNow(new DrawEnvelopeResp(this.uid, reward));
        return new EcResult().success();
    }

    /**
     * @param remainAmount 红包剩余总金额
     * @param remainNum    红包剩余份数
     * @return
     */
    public int genRandomNum(GuildEnvelopeRow tpl, int remainAmount, int remainNum) {
        if (remainNum == 0) {
            return 0;
        }
        if (remainNum == 1) {
            return remainAmount;
        }
        // 保底金额
        int guarantee =
                (int) (tpl.amount / (double) tpl.redEnvelopeNum * GDGuild.redEnvelope.GUARANTEE_COEFFICIENT);
        // 本次抽红包可以额外抽到的最大金额数
        double available =
                ((remainAmount - remainNum * guarantee)
                        * GDGuild.redEnvelope.DISPERSION_COEFFICIENT);
        // 本次随机到的总金额
        int random = (int) (Math.random() * available) + guarantee;
        // 随机的金额如果太大则强制获取保底奖励
        if (remainAmount - random < guarantee * (remainNum - 1)) {
            return guarantee;
        } else {
            return random;
        }
    }
}
